"""
用户认证工具模块
提供JWT令牌管理、密码加密、权限验证等功能
"""
import jwt
import os
from datetime import datetime, timedelta
from functools import wraps
from flask import request, jsonify, current_app
from werkzeug.security import generate_password_hash, check_password_hash
from models import User, db


class AuthManager:
    """用户认证管理器"""
    
    @staticmethod
    def hash_password(password):
        """
        对密码进行哈希加密
        
        Args:
            password (str): 原始密码
            
        Returns:
            str: 加密后的密码哈希值
        """
        return generate_password_hash(password)
    
    @staticmethod
    def verify_password(password_hash, password):
        """
        验证密码是否正确
        
        Args:
            password_hash (str): 存储的密码哈希值
            password (str): 用户输入的密码
            
        Returns:
            bool: 密码是否正确
        """
        return check_password_hash(password_hash, password)
    
    @staticmethod
    def generate_token(user_id, role='user'):
        """
        生成JWT令牌
        
        Args:
            user_id (int): 用户ID
            role (str): 用户角色，默认为'user'
            
        Returns:
            str: JWT令牌字符串
        """
        payload = {
            'user_id': user_id,
            'role': role,
            'exp': datetime.utcnow() + timedelta(hours=24),  # 24小时过期
            'iat': datetime.utcnow()
        }
        
        secret_key = os.getenv('JWT_SECRET_KEY', 'your-secret-key-change-in-production')
        return jwt.encode(payload, secret_key, algorithm='HS256')
    
    @staticmethod
    def verify_token(token):
        """
        验证JWT令牌
        
        Args:
            token (str): JWT令牌
            
        Returns:
            dict or None: 解码后的payload，验证失败返回None
        """
        try:
            secret_key = os.getenv('JWT_SECRET_KEY', 'your-secret-key-change-in-production')
            payload = jwt.decode(token, secret_key, algorithms=['HS256'])
            return payload
        except jwt.ExpiredSignatureError:
            return None
        except jwt.InvalidTokenError:
            return None


def token_required(f):
    """
    JWT令牌验证装饰器
    验证请求头中的Authorization令牌
    
    Args:
        f: 被装饰的函数
        
    Returns:
        function: 装饰后的函数
    """
    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        
        # 从请求头获取令牌
        if 'Authorization' in request.headers:
            auth_header = request.headers['Authorization']
            try:
                token = auth_header.split(' ')[1]  # Bearer <token>
            except IndexError:
                return jsonify({'message': '令牌格式错误'}), 401
        
        if not token:
            return jsonify({'message': '缺少访问令牌'}), 401
        
        # 验证令牌
        payload = AuthManager.verify_token(token)
        if payload is None:
            return jsonify({'message': '令牌无效或已过期'}), 401
        
        # 获取用户信息
        current_user = User.query.get(payload['user_id'])
        if not current_user:
            return jsonify({'message': '用户不存在'}), 401
        
        # 将用户信息传递给被装饰的函数
        return f(current_user, *args, **kwargs)
    
    return decorated


def admin_required(f):
    """
    管理员权限验证装饰器
    要求用户必须是管理员角色
    
    Args:
        f: 被装饰的函数
        
    Returns:
        function: 装饰后的函数
    """
    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        
        # 从请求头获取令牌
        if 'Authorization' in request.headers:
            auth_header = request.headers['Authorization']
            try:
                token = auth_header.split(' ')[1]
            except IndexError:
                return jsonify({'message': '令牌格式错误'}), 401
        
        if not token:
            return jsonify({'message': '缺少访问令牌'}), 401
        
        # 验证令牌
        payload = AuthManager.verify_token(token)
        if payload is None:
            return jsonify({'message': '令牌无效或已过期'}), 401
        
        # 检查用户角色
        if payload.get('role') != 'admin':
            return jsonify({'message': '需要管理员权限'}), 403
        
        # 获取用户信息
        current_user = User.query.get(payload['user_id'])
        if not current_user:
            return jsonify({'message': '用户不存在'}), 401
        
        return f(current_user, *args, **kwargs)
    
    return decorated


def validate_password(password):
    """
    验证密码强度
    
    Args:
        password (str): 密码字符串
        
    Returns:
        tuple: (是否有效, 错误消息)
    """
    if len(password) < 6:
        return False, "密码长度至少6个字符"
    
    return True, ""


def validate_email(email):
    """
    验证邮箱格式
    
    Args:
        email (str): 邮箱地址
        
    Returns:
        bool: 邮箱格式是否有效
    """
    import re
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return re.match(pattern, email) is not None
